#include "StdAfx.h"
#include <cassert>
#include "Hook.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace pktoon
{
	LRESULT CALLBACK InputHook::LowLevelKeybdProc( int aCode, WPARAM wParam, LPARAM lParam )
	{
		return InputHook::Instance()->OnKeybdProc(aCode, wParam, lParam);
	}

	LRESULT CALLBACK InputHook::LowLevelMouseProc( int aCode, WPARAM wParam, LPARAM lParam )
	{
		return InputHook::Instance()->OnMouseProc(aCode, wParam, lParam);
	}

	LRESULT InputHook::OnKeybdProc( int aCode, WPARAM wParam, LPARAM lParam )
	{
		ASSERT(mListener);
		if (aCode == HC_ACTION && lParam != 0 && mListener->OnKey(wParam, *(KBDLLHOOKSTRUCT*)lParam))
		{
			return TRUE;
		}
		return CallNextHookEx(mKeyHook, aCode, wParam, lParam);
	}

	LRESULT InputHook::OnMouseProc( int aCode, WPARAM wParam, LPARAM lParam )
	{
		ASSERT(mListener);
		if (aCode == HC_ACTION && lParam != 0 && mListener->OnMouse(wParam, *(MSLLHOOKSTRUCT*)lParam))
		{
			return TRUE;
		}
		return CallNextHookEx(mMouseHook, aCode, wParam, lParam);
	}

	bool InputHook::Start()
	{
		if (mStartKey)
		{
			mKeyHook = ::SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeybdProc, AfxGetApp()->m_hInstance, 0);
			if (!mKeyHook)
			{
				LogError("init key hook failed");
				return false;
			}
		}
		
		if (mStartMouse)
		{
			mMouseHook = ::SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, AfxGetApp()->m_hInstance, 0);
			if (!mMouseHook)
			{
				LogError("init mouse hook failed");
				return false;
			}
		}
		
		return true;
	}

	bool InputHook::Stop()
	{
		UnhookWindowsHookEx(mKeyHook);
		UnhookWindowsHookEx(mMouseHook);
		return true;
	}
}	